const path = require( 'path' );
const webpack = require( 'webpack' );
const resolve = ( file ) => path.resolve( __dirname, file );
const isProduction = process.env.NODE_ENV === 'production';

const LodashModuleReplacementPlugin = require("lodash-webpack-plugin");
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');

module.exports = {
  // 基本路径
  /* 部署生产环境和开发环境下的URL：可对当前环境进行区分，baseUrl 从 Vue CLI 3.3 起已弃用，要使用publicPath */
  publicPath: isProduction ? "./" : "./",
  // 将构建好的文件输出到哪里（或者说将编译的文件）
  outputDir: 'dist',
  // 放置静态资源的地方 (js/css/img/font/...)
  assetsDir: 'static',
  // 使用带有浏览器内编译器的完整构建版本
  // 查阅 https://cn.vuejs.org/v2/guide/installation.html#运行时-编译器-vs-只包含运行时
  // runtimeCompiler: true,
  // 是否在保存的时候使用 `eslint-loader` 进行检查。
  // 有效的值：`ture` | `false` | `"error"`
  // 当设置为 `"error"` 时，检查出的错误会触发编译失败。
  lintOnSave: false,
  // babel-loader 默认会跳过 node_modules 依赖。
  // 通过这个选项可以显式转译一个依赖。
  transpileDependencies: [/* string or regex */ ],
  // 是否为生产环境构建生成 source map？
  productionSourceMap: true,
  filenameHashing: true,
  chainWebpack: config => {
    config.resolve.symlinks( true );
    config.plugin("html").tap(args =>{
      args[0].chunksSortMode = "none";
      return args;
    });
    config.module.rule('fonts').use('url-loader').loader('url-loader').options({
      limit: 10000,
      name: 'static/fonts/[hash:16].[ext]'
    });
    
    config.resolve.alias
      .set( 'vue$', "vue/dist/vue.esm.js" )
      .set( '@', resolve( 'src' ) )
      .set( '@assets', resolve( 'src/assets' ) )
      .set( '@components', resolve( 'src/components' ) )
      .set( '@config', resolve( 'src/config' ) )
      .set( '@plugins', resolve( 'src/plugins' ) )
      .set( '@service', resolve( 'src/service' ) )
      .set( '@views', resolve( 'src/views' ) );
  
    config.module.rule( 'vue' )
      .use( 'vue-loader' )
      .loader( 'vue-loader' )
      .tap( options => {
        options.compilerOptions.preserveWhitespace = true;
        return options
      } )
      .end();
    config.plugins.delete('prefetch');
    config.plugins.delete('preload');
    config.plugin('loadshReplace').use(new LodashModuleReplacementPlugin());
    
    const splitOptions = config.optimization.get( 'splitChunks' );
    config.optimization.splitChunks(
      Object.assign( {}, splitOptions, {
        chunks: "all",
        // （缺省值5）按需加载时的最大并行请求数
        maxAsyncRequests: 16,
        // （默认值3）入口点上的最大并行请求数
        maxInitialRequests: Infinity,
        // （默认值：1）分割前共享模块的最小块数
        minChunks: 1,
        // （默认值：30000）块的最小大小
        minSize: 20000,
        // webpack 将使用块的起源和名称来生成名称: `vendors~main.js`,如项目与"~"冲突，则可通过此值修改，Eg: '-'
        automaticNameDelimiter: '-',
        // cacheGroups is an object where keys are the cache group names.
        name: true,
        cacheGroups: {
          page: {
            name: "chunk-page",
            test: /[\\/]src[\\/]/,
            // chunks: "all",
            priority: 10,
            reuseExistingChunk: true,
            enforce: true,
          },
          antDesignVue: {
            name: 'chunk-ant-design-vue', // split antdui into a single package
            test: /[\\/]node_modules[\\/]_?ant-design-vue(.*)/, // in order to adapt to cnpm
            // chunks: "all",
            priority: 100, // the weight needs to be larger than libs and app or it will be packaged into libs or app
            reuseExistingChunk: true,
            enforce: true,
          },
          vendors: {
            name: "chunk-vendors",
            test: /[\\/]node_modules[\\/]/,
            // chunks: "all",
            priority: 20,
            reuseExistingChunk: true,
            enforce: true,
          },
        }
      } )
    );
  },
  configureWebpack: config => {
    config.output.filename = `js/[name].[hash:8].js`;
    config.output.chunkFilename = `js/[name].[hash:8].js`;
    config.performance = {
      hints: 'warning',
      //入口起点的最大体积 整数类型（以字节为单位）
      maxEntrypointSize: 50000000,
      //生成文件的最大体积 整数类型（以字节为单位 300k）
      maxAssetSize: 30000000,
      //只给出 js 文件的性能提示
      assetFilter: function ( assetFilename ) {
        return assetFilename.endsWith( '.js' );
      }
    };
    config.modules
    
    
    
    config.plugins.push(
      new webpack.ContextReplacementPlugin(/moment[\\\/]locale$/, /^\.\/(zh-cn)$/),
      new HardSourceWebpackPlugin(),
    )
  },
  // CSS 相关选项
  css: {
    // 将组件内的 CSS 提取到一个单独的 CSS 文件 (只用在生产环境中)
    // 也可以是一个传递给 `extract-text-webpack-plugin` 的选项对象
    extract: true,
    // 是否开启 CSS source map？
    sourceMap: false,
    // 为预处理器的 loader 传递自定义选项。比如传递给
    loaderOptions: {
      less: {
        // modifyVars: {
        //   'primary-color': '#1DA57A',
        //   'link-color': '#1DA57A',
        //   'border-radius-base': '4px',
        //   'input-border-color': '#e2e5ec'
        // },
        // modifyVars: darkTheme,
        javascriptEnabled: true
      }
    },
    // 为所有的 CSS 及其预处理文件开启 CSS Modules。
    // 这个选项不会影响 `*.vue` 文件。
    requireModuleExtension: true
  },
  // 在生产环境下为 Babel 和 TypeScript 使用 `thread-loader`
  // 在多核机器下会默认开启。
  parallel: require( 'os' ).cpus().length > 1,
  devServer: {
    open: process.platform === 'darwin',
    host: '0.0.0.0',
    port: 8080,
    https: false,
    hotOnly: false,
    disableHostCheck: true,
    // 查阅 https://github.com/vuejs/vue-docs-zh-cn/blob/master/vue-cli/cli-service.md#配置代理
    // proxy: {
    //   '/api': {
    //     target: 'http://localhost:8880',
    //     changeOrigin: true,
    //     secure: false,
    //     // ws: true,
    //     pathRewrite: {
    //       '^/api': '/static/mock'   // 请求数据路径别名,这里是注意将static/mock放入public文件夹
    //     }
    //   }
    // },
    before: app => {
    }
  },
  // 三方插件的选项
  pluginOptions: {
    // ...
  }
};
